/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.sangcomz.fishbun.util;

import ohos.agp.components.*;
import ohos.app.Context;
import ohos.hiviewdfx.HiLog;
import ohos.hiviewdfx.HiLogLabel;

import java.util.ArrayList;
import java.util.List;

public abstract class BaseGridSliceProvider<T,VH extends BaseGridSliceProvider.BaseViewHolder> extends BaseItemProvider {

    private HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG, 0x123, "BaseGridSliceProvider");

    private GridItemClickListener itemClickListener;
    private int indexCount = 2; //设置列数
    protected List<T> itemData;
    private Context context;
    private int resId = -1;
    private DirectionalLayout.LayoutConfig layoutConfig;
    private GridConfig gridConfig;
    private int padding;

    /**
     * Grid相关配置信息
     */
    public static class GridConfig {
        private int indexCount = 2; //设置列数
        private int padding = 8; //设置间隔
        private int itemHeight = -1; //设置item的高度

        public int getIndexCount() {
            if (indexCount <= 0) {
                return 1;
            }
            return indexCount;
        }

        public void setIndexCount(int indexCount) {
            this.indexCount = indexCount;
        }

        public int getPadding() {
            if (padding < 0) {
                return 0;
            }
            return padding;
        }

        public void setPadding(int padding) {
            this.padding = padding;
        }

        public int getItemHeight() {
            return itemHeight;
        }

        public void setItemHeight(int itemHeight) {
            this.itemHeight = itemHeight;
        }
    }

    public BaseGridSliceProvider(Context context,List<T> itemData, int resId) {
        this(context, itemData, resId, null);
    }

    /**
     *
     * @param context
     * @param itemData 填充数据
     * @param resId 填充布局
     * @param gridConfig 布局的配置信息
     */
    public BaseGridSliceProvider(Context context, List<T> itemData, int resId, GridConfig gridConfig) {
        this.context = context;
        this.itemData = itemData;
        this.resId = resId;

        setLayoutConfig(gridConfig);
    }

    /**
     * 修改配置信息
     * @param gridConfig
     */
    public void setLayoutConfig(GridConfig gridConfig) {

        int itemPadding = 8;

        if (gridConfig != null) {
            itemPadding = gridConfig.getPadding();
            indexCount = gridConfig.getIndexCount();
            this.gridConfig = gridConfig;
        }

        padding = AttrHelper.vp2px(itemPadding, context);
        int width = AttrHelper.vp2px(context.getResourceManager().getDeviceCapability().width, context);

        int itemWidth = (width - padding * indexCount * 2) / indexCount;
        int itemHeight = itemWidth;
        if (gridConfig != null && gridConfig.itemHeight >= 0) {
            itemHeight = AttrHelper.vp2px(gridConfig.itemHeight, context);
        }
        layoutConfig = new DirectionalLayout.LayoutConfig(itemWidth, itemHeight);
        layoutConfig.setMargins(padding, padding, padding, padding);

        notifyDataChanged();
    }

    public interface GridItemClickListener {
        /**
         * 子view的点击事件的回调
         *
         * @param component     被点击的控件对象
         * @param position      被点击的控件对象所在数据列表中的位置
         * @param indexPosition 被点击的控件对象所在列的位置
         */
        void onItemClicked(Component component, int position, int indexPosition);
    }

    /**
     * 添加子view的点击事件
     *
     * @return
     */
    public BaseGridSliceProvider setItemClickListener(GridItemClickListener itemClickListener) {
        this.itemClickListener = itemClickListener;
        return this;
    }

    public BaseGridSliceProvider setIndexCount(int indexCount) {
        if (indexCount <= 0) {
            this.indexCount = 2;
        } else {
            this.indexCount = indexCount;
        }
        return this;
    }

    public Context getContext() {
        return context;
    }

    @Override
    public int getCount() {
        if (itemData != null) {
            int last = itemData.size() % indexCount == 0 ? 0 : 1;
            return itemData.size() / indexCount + last;
        }
        return 0;
    }

    @Override
    public T getItem(int i) {
        if (itemData != null && i >= 0 && i < itemData.size()) {
            return itemData.get(i);
        }
        return null;
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public Component getComponent(int position, Component component, ComponentContainer componentContainer) {

        if (itemData == null || itemData.isEmpty()) {
            return null;
        }

        Component cpt;

        if (component == null) {
            cpt = setComponent(position);
            setChildTag(position, cpt);
        } else {
            cpt = component;
        }
        checkViewStatus(position, cpt);
        setViewHolderData(position,cpt);

        return cpt;
    }

    /**
     * 判断每一行的view是否显示了需要的个数，避免因为复用机制导致某一行显示了多余的子view
     */
    private void checkViewStatus(int position, Component component) {
        if (!(component instanceof DirectionalLayout) || itemData == null) {
            return;
        }
        DirectionalLayout itemView = (DirectionalLayout) component;
        int showChildCount = indexCount;
        int childCount = itemView.getChildCount();
        if (indexCount == 1) {
            showChildCount = 1;
        }else if (position == getCount() - 1) {
            showChildCount = itemData.size() % indexCount;
        }
        for (int i = 0; i < childCount; i++) {
            int childPosition = position * indexCount + i;
            Component childView = itemView.getComponentAt(i);
            if (i < showChildCount) {
                childView.setVisibility(Component.VISIBLE);

                childView.setClickedListener(new Component.ClickedListener() {
                    @Override
                    public void onClick(Component component) {
                        if (itemClickListener != null) {
                            itemClickListener.onItemClicked(childView, childPosition, position);
                        }
                    }
                });

            } else {
                childView.setVisibility(Component.HIDE);
            }
        }
    }

    /**
     * 设置每个item的数据
     * @param position
     * @param component
     */
    private void setViewHolderData(int position, Component component) {

        if (!(component instanceof DirectionalLayout)) {
            return;
        }
        DirectionalLayout itemView = (DirectionalLayout) component;

        for (int i = 0; i < itemView.getChildCount(); i++) {
            Component child = itemView.getComponentAt(i);
            try {
                VH viewHolder = (VH) child.getTag();
                if (viewHolder == null) {
                    continue;
                }
                int childPosition = position * indexCount + i;
                int viewType = getItemViewType(childPosition);
                onBindViewHolder(viewHolder, getItem(childPosition), viewType, childPosition, position);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 初始化设置Component
     * @param position
     * @return
     */
    private DirectionalLayout setComponent(int position) {
        DirectionalLayout itemView = new DirectionalLayout(context);
        itemView.setOrientation(Component.HORIZONTAL);
        itemView.setWidth(ComponentContainer.LayoutConfig.MATCH_PARENT);
        int count = 0;
        if (itemData.size() < indexCount || position + 1 > itemData.size() / indexCount) {
            count = itemData.size() % indexCount;
        } else {
            count = indexCount;
        }
        for (int i = 0; i < count; i++) {
            int childPosition = position * indexCount + i;
            int childResId = getItemResId(getItemViewType(childPosition));
            Component child = LayoutScatter.getInstance(getContext()).parse(childResId, null, false);

            if (child != null) {

                child.setLayoutConfig(layoutConfig);

                itemView.addComponent(child);

            }
        }
        return itemView;
    }

    /**
     * 为每一个child view绑定viewholder
     * @param position
     * @param component
     */
    private void setChildTag(int position, Component component) {
        if (!(component instanceof DirectionalLayout)) {
            return;
        }
        DirectionalLayout itemView = (DirectionalLayout) component;

        for (int i = 0; i < itemView.getChildCount(); i++) {
            Component child = itemView.getComponentAt(i);
            int childPosition = position * indexCount + i;
            try {
                VH viewHolder = onCreateViewHolder(child, childPosition);
                if (viewHolder == null) {
                    continue;
                }
//                viewHolderList.add(viewHolder);
//                HiLog.debug(TAG, "position view holder hash code : " + viewHolder);
                child.setTag(viewHolder);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 设置数据
     * @param viewHolder
     * @param data
     * @param viewType view类型
     * @param position 真实view的位置
     * @param indexPosition 真实view所在的行
     */
    public abstract void onBindViewHolder(VH viewHolder,T data,int viewType ,int position, int indexPosition);

    public abstract VH onCreateViewHolder(Component component, int viewType);

    public abstract class BaseViewHolder {

        public BaseViewHolder(Component component) {

        }
    }

    /**
     * 设置多种布局
     * @param position
     * @return
     */
    private int getItemViewType(int position) {
        return 0;
    }

    /**
     * 根据item view type获取相应的布局
     * @return
     */
    public int getItemResId(int type) {
        return resId;
    }


}
